home *** CD-ROM | disk | FTP | other *** search
- package sub_arctic.lib;
-
- import sub_arctic.input.*;
- import sub_arctic.output.*;
- import sub_arctic.lib.sub_arctic_error;
- import sub_arctic.constraints.std_function;
- import sub_arctic.constraints.constraint;
-
- /**
- *
- * @author Ian Smith
- */
- public class hierarchy_parent
- extends base_parent_interactor implements clickable {
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Keep track if we are open.
- */
- protected boolean _is_open;
- public boolean is_open() { return _is_open;};
- public void set_is_open(boolean i) {
- loaded_image img;
- icon the_icon;
-
- _is_open=i;
- /* If we have a special child, set his icon partner to be right */
- if (special_child()!=null) {
- /* which icon to use? */
- if (is_open()) {
- img=std.hm_down_arrow();
- } else {
- img=std.hm_right_arrow();
- }
- /* get the icon from the right spot */
- the_icon=(icon)child(0).child(0);
- /* reset the image */
- the_icon.set_image(img);
- }
- set_child_constraints();
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * We need to know if we are handling the first child management.
- */
- protected interactor _special_child;
-
- /**
- * This returns null if we aren't handling anything special for them.
- */
- public interactor special_child() { return _special_child;};
-
- /**
- * If you call this method the interactor you pass becomes the
- * first child. Note that you'll need to compensate for the
- * width of the triangle if you care about all objects being
- * equal width.
- */
- public void set_special_child(interactor b) {
- base_parent_interactor base;
- icon i;
-
- _special_child=b;
- /* are they setting it to null ?*/
- if (b==null) return;
-
- /* build a subtree that includes the icon and their interactor */
- base=new shrink_wrap_container(0,0,0,false);
-
- /* are we open or closed ?*/
- if (is_open()) {
- i=new icon(0,0,std.hm_down_arrow());
- } else {
- /*closed */
- i=new icon(0,0,std.hm_right_arrow());
- }
- /* stick in icon */
- base.add_child(i);
- /* put in their interactor */
- base.add_child(b);
- /* add these two to our interactor */
- if (num_children()==0) {
- add_child(base);
- }
- else {
- set_child(0,base);
- }
- /* setup the child constraints */
- set_child_constraints();
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Border around our edges. */
- int _border;
-
- /**
- * Border around our edges.
- * @return int the border size.
- */
- int border() { return _border;};
-
- /**
- * Set the border around our edges.
- * @param int b the new border size.
- */
- void set_border(int b) {
- _border=b;
- set_child_constraints();
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Space between children. */
- int _interchild_space;
-
- /**
- * Space between our children
- *
- * @return int the amount of vertical spacing maintained between our children.
- */
- int interchild_space() { return _interchild_space;};
-
- /**
- * Set the amount of space maintained between children
- */
- void set_interchild_space(int b)
- {
- _interchild_space=b;
- set_child_constraints();
- };
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This builds the constraints for the children. This is at init time
- * and again if any of the spacing parameters changes.
- */
- protected void set_child_constraints() {
- int i, max = num_children();
- interactor current_child,icon, tmp;
- constraint strut_between_children, xposition = null;
-
- /* loop over all children */
- for (i=0; i<max; ++i) {
-
- /* set the current child */
- current_child = child(i);
-
- /* drop the current constraints, if any */
- current_child.set_x_constraint(NO_CONSTRAINT);
- current_child.set_y_constraint(NO_CONSTRAINT);
-
- /* is it the first child? */
- if (i != 0) {
- /* this is the strut which keeps the y position of a child
- * below the previous child and possibly shifts it over */
- strut_between_children = std_function.offset(PREV_SIBLING.Y2(),
- interchild_space());
- current_child.set_y_constraint(strut_between_children);
-
- /* if its not the first child , space it over */
- current_child.set_x_constraint(std_function.offset(PARENT.X(),
- border()+ indent_spacing()));
- } else {
- /* note that the constraints are different if we are open
- * or closed. This lets us enforce the border only when
- * we are open.
- */
- if (is_open()) {
- /* i is zero, setup the top constraint */
- strut_between_children = std_function.offset(PARENT.Y(), border());
- current_child.set_y_constraint(strut_between_children);
-
- /* first child is not indented */
- current_child.set_x_constraint(std_function.offset(PARENT.X(),
- border()));
- } else { /* this is the closed case */
- /* just put it at 0,0 so we don't do anything to it */
- current_child.set_x(0);
- current_child.set_y(0);
- }
- }
- }
-
- /* do we have a special child #0? */
- if (special_child()!=null) {
- /* extract children */
- icon=child(0).child(0);
- tmp=child(0).child(1);
-
- /* set up the constraints for layout in x*/
- icon.set_x_constraint(std_function.offset(PARENT.X(),0));
- tmp.set_x_constraint(std_function.offset(PREV_SIBLING.X2(), 0));
-
- /* center them next to each other in y*/
- if (icon.h()>tmp.h()) {
- icon.set_y(0);
- tmp.set_y((icon.h()-tmp.h())/2);
- } else {
- icon.set_y((tmp.h()-icon.h())/2);
- tmp.set_y(0);
- }
- }
-
- /* do our constraints and size computation */
- set_local_constraints();
- damage_self();
-
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Set up our own constraints. This is done at init time and again if
- * we every redo the child constraints.
- */
- void set_local_constraints() {
- /* are there children? */
- if (num_children()==0) {
- /* drop constraints */
- set_h_constraint(NO_CONSTRAINT);
- set_w_constraint(NO_CONSTRAINT);
-
- /* set w/h manually to be twice the border */
- set_h(2*border());
- set_w(2*border());
- return;
- }
-
- /* we have children... are we open */
- if (is_open()) {
- /* just do the max of our children */
- set_h_constraint(std_function.offset(MAX_CHILD.Y2(), border()));
-
- /* just do the max of our children */
- set_w_constraint(std_function.offset(MAX_CHILD.X2(), border()));
-
- } else {
- /* set the no constraint */
- set_w_constraint(NO_CONSTRAINT);
- set_h_constraint(NO_CONSTRAINT);
- /* note: we don't want the border if we are closed because
- * we want to show no difference from child(0).
- */
- set_h(child(0).h());
- set_w(child(0).w());
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Override the way child drawing is done.
- * @param drawable d the drawing surface we produce our result on.
- */
- protected void draw_children(drawable d)
- {
- /* if we are in the normal state, just draw them */
- if (is_open()) {
- super.draw_children(d);
- } else {
- /* we are closed, just draw first child */
- child(0).draw_self(d);
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** This holds the amount that children in the hierarchy are indented. */
- protected int _indent_spacing;
-
- /**
- * The amount that children in the hierarchy are indented.
- * @return int indentation amount.
- */
- public int indent_spacing() { return _indent_spacing;};
-
- /**
- * Set the amount that children in the hierarchy are indented.
- * @param int s new indentation amount.
- */
- public void set_indent_spacing(int s) {
- _indent_spacing=s;
- set_child_constraints();
- damage_self();
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Build a hierarchy object, which is a special type of parent.
- * The first object is always displayed, children 1 through n-1 are displayed
- * only if the manager is open. It defaults to being closed.
- * This object steals the press event from its first child.
- *
- * @param int xv the x position of the interactor.
- * @param int yv the y position of the interactor.
- * @param int the_border the size of the border around our
- * children.
- * @param int the_interchild_spacing vertical space between children.
- * @param int the_indent_spacing amount to indent children.
- */
- public hierarchy_parent(int xv, int yv, int the_border,
- int the_interchild_spacing,
- int the_indent_spacing)
- {
-
- /* constraints take care of w,h */
- super(xv,yv);
-
- _indent_spacing=the_indent_spacing;
- _interchild_space=the_interchild_spacing;
- _border=the_border;
- _special_child=null;
- set_is_open(false);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This builds a default hierarchy manager with no border, interchild
- * spacing of 2, and indent spacing of 15. It also defaults to being
- * closed.
- *
- * @param int xv the x position of the interactor.
- * @param int yv the y position of the interactor.
- */
- public hierarchy_parent(int xv, int yv)
- {
- super(xv,yv);
- _indent_spacing=15;
- _interchild_space=2;
- _special_child=null;
- _border=0;
- set_is_open(false);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This builds a default hierarchy manager with default position of 0,0,
- * no border, interchild spacing of 2, and indent spacing of 15. It also
- * defaults to being closed.
- */
- public hierarchy_parent()
- {
- super(0,0);
- _indent_spacing=15;
- _interchild_space=2;
- _special_child=null;
- _border=0;
- set_is_open(false);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This causes the hierarchy to "open up".
- */
- public void open()
- {
- interactor chld;
-
- /* don't bother if open */
- if (is_open()) return;
- set_is_open(true);
- }
-
- //had:
- //* @exception general
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This causes the hierarchy to "close up".
- */
- public void close()
- {
- interactor chld;
-
- /* don't bother if already closed */
- if (!is_open()) return;
- set_is_open(false);
- }
-
- //had:
- //* @exception general
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This is the input stealer for the first object. We use clicks over the
- * first child to trigger opening and closing, so we test here whether the
- * first child was picked, and if so we claim to be picked also.
- *
- * @param int pt_x the x coordinate of the query point.
- * @param int pt_y the y coordinate of the query point.
- */
- public void pick(int pt_x, int pt_y, pick_collector pick_list)
- {
- int i;
- user_info_holder h;
-
- pick_within_children(pt_x,pt_y,pick_list);
-
- /* loop over everyone picked */
- for (i=0; i<pick_list.num_picks(); ++i) {
- h=pick_list.pick(i);
-
- /* if child #0 is in the list, we are picked also */
- if (find_child(h.obj)==0) {
- pick_list.report_pick(this);
- }
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Handle click input. We get this when a click occurs over our first child
- * (and the child does not itself consume the click).
- *
- * @param event evt the release event.
- * @param Object ui user_info passed to the pick (ignored).
- */
- public boolean click(event evt, Object ui) {
- /* reverse the state */
- if (is_open()) {
- close();
- }
- else {
- open();
- }
- return true;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /* these are copied right out the column code */
- /* note: it appears to me that the column (and the hierarchy
- manager) should not be converted to incremental addition
- of constraints as this makes them MUCH harder to subclass */
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Override to also add constraints.
- * @param interactor chld the child object being added.
- */
- public void add_child(interactor chld)
- {
- super.add_child(chld);
- set_child_constraints();
- }
-
- //had:
- //* @exception op_not_supported if this object does not support children or
- //* has fixed children (shouldn't happen).
- //* @exception general
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Override to also add constraints.
- * @param int at_indx index where the child goes.
- * @param interactor chld the child object to insert at that index
- */
- public void insert_child(int at_indx, interactor chld)
- {
- super.insert_child(at_indx,chld);
- set_child_constraints();
- }
-
- //had:
- //* @exception op_not_supported if this object does not support children or
- //* has fixed children (shouldn't happen).
- //* @exception general
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Override to also add constraints
- * @param int at_indx index of child to be removed.
- */
- public interactor remove_child(int at_indx)
- {
- interactor i;
-
- i=super.remove_child(at_indx);
- set_child_constraints();
- return i;
- }
-
- //had:
- //* @exception op_not_supported if this object does not support children
- //* (shouldn't happen).
- //* @exception general
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Override to also add constraints.
- * @param interactor the_child the child to remove.
- */
- public void remove_child(interactor the_child)
- {
- super.remove_child(the_child);
- set_child_constraints();
- }
-
- //had:
- //* @exception op_not_supported if this object does not support children
- //* (shouldn't happen).
- //* @exception general
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
- }
- /*=========================== COPYRIGHT NOTICE ===========================
-
- This file is part of the subArctic user interface toolkit.
-
- Copyright (c) 1996 Scott Hudson and Ian Smith
- All rights reserved.
-
- The subArctic system is freely available for most uses under the terms
- and conditions described in
- http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html
- and appearing in full in the lib/interactor.java source file.
-
- The current release and additional information about this software can be
- found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
-
- ========================================================================*/
-